﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using OpenQuarters.WebQuarters.Utils;

namespace OpenQuarters.WebQuarters.Core
{
    public partial class WorkflowItem : CMSEntity<WorkflowItem, long>
    {
        public FriendlyDictionary<string, List<MethodInfo>> WorkflowItemHandlers
        {
            get
            {
                var r = new FriendlyDictionary<string, List<MethodInfo>>();
                foreach (var m in GeneralUtils.GetMethodsWithAttribute<WorkflowItemHandlerAttribute, WorkflowItemHandlerContainerAttribute>())
                {
                    var attr = (WorkflowItemHandlerAttribute)m.GetCustomAttributes(typeof(WorkflowItemHandlerAttribute), true)[0];
                    r[attr.Operation + " " + attr.TargetType].Add(m);
                }
                return r;
            }
        }

        public static List<WorkflowItem> OpenItems
        {
            get
            {
                return Table.Where(e => e.Status == WorkflowItemStatus.Open).ToList();
            }
        }

        [Newtonsoft.Json.JsonProperty]
        public long json_WorkflowItemId
        {
            get { return this.WorkflowItemId; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Category
        {
            get { return this.Category; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Operation
        {
            get { return this.Operation; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_TargetName
        {
            get { return this.TargetName; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_TargetType
        {
            get { return this.TargetType; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Status
        {
            get { return this.Status.ToString(); }
        }

        public Permission RequiredPermission
        {
            get
            {
                return new Permission()
                {
                    Name = RequiredPermissionName,
                    Value = RequiredPermissionValue
                };
            }
            set
            {
                this.RequiredPermissionName = value.Name;
                this.RequiredPermissionValue = value.Value;
            }
        }

        private bool? currentUserHasPermission = null;

        public bool CurrentUserHasPermission
        {
            get
            {
                if (!currentUserHasPermission.HasValue)
                {
                    currentUserHasPermission = Core.User.Current.HasPermission(this.RequiredPermissionName, this.RequiredPermissionValue);
                }
                return currentUserHasPermission.Value;
            }
            set { currentUserHasPermission = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public bool json_CurrentUserHasPermission
        {
            get { return CurrentUserHasPermission; }
        }

        [Newtonsoft.Json.JsonProperty]
        public List<WorkflowComment> json_Comments
        {
            get { return WorkflowComment.Table.Where(e => e.WorkflowItemId == this.WorkflowItemId).OrderByDescending(e => e.DateCreated).ToList(); }
        }

        public override System.Linq.Expressions.Expression<Func<WorkflowItem, bool>> GetIDSelector(long ID)
        {
            return e => e.WorkflowItemId == ID;
        }

        public override long GetKey(WorkflowItem Entity)
        {
            return Entity.WorkflowItemId;
        }

        public override void OnSaving()
        {
            base.OnSaving();

            this.LoggingMode = LoggingMode.Off;
        }

        public override void OnDeleting()
        {
            base.OnDeleting();
            this.WorkflowComments.ToList().ForEach(e => e.Delete());
        }

        public override string ToString()
        {
            return this.json_Operation + " " + this.json_TargetType + " " + this.json_TargetName;
        }

        public void Approve()
        {
            foreach (var handler in WorkflowItemHandlers[this.Operation + " " + this.TargetType])
            {
                handler.Invoke(null, new object[] { this });
            }
            this.Status = WorkflowItemStatus.Approved;
            this.Save();
        }

        public void Reject()
        {
            this.Status = WorkflowItemStatus.Rejected;
            this.Save();
        }

        private void deleteRecursively()
        {
            UserMessage.Table.Where(e => e.WorkflowItemId == this.WorkflowItemId).ToList().ForEach(e => e.Delete());
            WorkflowComment.Table.Where(e => e.WorkflowItemId == this.WorkflowItemId).ToList().ForEach(e => e.Delete());
            this.Delete();
        }
    }
}
